package com.cloudloan.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudloan.annotion.PageSelect;
import com.cloudloan.common.R;
import com.cloudloan.enmus.StatusName;
import com.cloudloan.entity.CustomPage;
import com.cloudloan.entity.LoginUser;
import com.cloudloan.entity.User;
import com.cloudloan.mapper.LoginMapper;
import com.cloudloan.service.LoginServcie;
import com.cloudloan.utils.AdministratorThreadLocal;
import com.cloudloan.utils.JwtUtil;
import com.cloudloan.utils.RedisUtils;
import com.cloudloan.utils.SaltMD5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
@Transactional
public class LoginServiceImpl extends ServiceImpl<LoginMapper,User> implements LoginServcie {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private LoginMapper loginMapper;
    @Override
    public R login(User user) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getPhone(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);  //确认密码是否正确
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误");
        }
        LoginUser principal = (LoginUser)authenticate.getPrincipal();
        User sysuser = principal.getUser();
        if(sysuser.getStatus()==1){
            return R.error("此用户已被禁用");
        }
        sysuser.setPassword(null);
        String phone = sysuser.getPhone();
        String jwt = JwtUtil.createJWT(phone);
        redisUtils.setCacheObject("login:"+sysuser.getPhone(),sysuser);
        HashMap<String,Object> map=new HashMap<>();
        map.put("token",jwt);
        return R.success(map, "登录成功");
    }

    /**
     * 退出登录
     * @return
     */
    @Override
    public R logout() {
        //获取SecurityContextHolder中的用户id
        User sysUser = AdministratorThreadLocal.getAdministrator();
        String phone = sysUser.getPhone();
        AdministratorThreadLocal.removeAdministrator();
        redisUtils.deleteObject("login:"+phone);
        return R.success("退出成功");
    }

    /**
     * 查询用户
     * @param id
     * @return
     */
    @Override
    public R getUserId(Long id) {
        //查询用户
        User user = loginMapper.selectById(id);
        if (user!=null) {
            user.setPassword(null);
        }else{
            return R.error("未跟据用户id查询到用户信息");
        }
        user.setStatusName(StatusName.getName(user.getStatus()));
        return R.success(user,"查询成功");
    }

    /**
     * 保存用户
     * @param user
     * @return
     */
    @Override
    public R saveUser(User user) {
        String newPassw = SaltMD5Utils.generateSaltPassword(user.getPassword().trim());
        user.setPassword(newPassw);

        return loginMapper.insert(user)>0?R.success("保存成功"):R.error("保存失败");
    }

    /**
     * 修改用户信息
     * @param user
     * @return
     */
    @Override
    public R updateUser(User user) {
        //先判断用户是否存在
        User user1 = loginMapper.selectById(user);
        if (user1==null){
            return R.error("未跟据用户id查询到用户信息");
        }
        if(user.getPassword()!=null){  //修改密码的情况
            String newPassw = SaltMD5Utils.generateSaltPassword(user.getPassword());
            user.setPassword(newPassw);
            int i = loginMapper.updateById(user);
            if (i>0){
                Object cacheObject = redisUtils.getCacheObject("login:" + user1.getPhone());
                if (cacheObject!=null){
                    redisUtils.deleteObject("login:" + user1.getPhone());
                }
            }
            return R.success("修改成功");
        }else {  //没修改密码的情况
            return loginMapper.updateById(user)>0?R.success("修改成功"):R.error("修改失败");
        }

    }

    /**
     * 删除用户信息
     * @param id
     * @return
     */
    @Override
    public R deleteById(Long id) {
        //查询原有数据
        User user = loginMapper.selectById(id);
        if (user==null){
            return R.error("未根据id查询出要删除的信息");
        }
        Object cacheObject = redisUtils.getCacheObject("login:" + user.getPhone());
        if (cacheObject!=null){
            redisUtils.deleteObject("login:" + user.getPhone());
        }
        return loginMapper.deleteById(id)>0?R.success("删除成功"):R.error("删除失败");
    }

    /**
     * 分页查询
     * @param page0
     * @param limit
     * @param map
     * @return
     */
    @Override
    @PageSelect
    public R selectPage(Integer page0, Integer limit, Map<String, Object> map) {
        //初始化分页参数
        Page<User> page=new Page<>(page0,limit);
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(map.get("phone")!=null&&!"".equals(map.get("phone")),
                User::getPhone,map.get("phone"))
                .like(map.get("name")!=null&&!"".equals(map.get("name")),
                        User::getName,map.get("name"));
        Page<User> page1 = loginMapper.selectPage(page, wrapper);
        for (User record : page1.getRecords()) {
            record.setPassword(null);
            record.setStatusName(StatusName.getName(record.getStatus()));
        }
        return R.success(page1);
    }
}
